package engine.render;

import engine.config.Config;
import engine.hw.Screen;
import engine.scene.Scene3D;
import engine.scene.TriGroup;
import engine.scene.TriGroupBuffer;

/*
 * OFFICIAL TO-DO LIST:
 *      Sound Support: OpenAL, almost finished preliminary additions
 *      Frustum Culling: TriGroup/AABB-vs-Frustum/Planes
 *      Integrated Lighting/Shadows: Lighting already do-able, Shadows are not.
 *      Physics: TriGroup/BoundingVolume and the rest of it
 *      
 */


public class Renderer
{
    
    private GLEngine glEngine;
    private ShaderEngine shaderEngine;
    
    private Scene3D scene;
    //<editor-fold defaultstate="collapsed" desc="setSceneTo">
    public void setSceneTo(Scene3D sceneOther)
    {
        this.scene = sceneOther;
    }
    //</editor-fold>
    
    public Renderer(Config cfg)
    {
        this.glEngine = new GLEngine();
        this.glEngine.setGLStates();
        this.glEngine.setViewportSize(
            Screen.get().getCurrentW(), 
            Screen.get().getCurrentH()
        );
        this.glEngine.setColorWrite(true);
        this.glEngine.setDepthWrite(true);
        this.shaderEngine = new ShaderEngine();
    }
    
    public void render()
    {
        this.glEngine.clearBuffers();
        
        this.shaderEngine.setShaderTo("normal");
        this.shaderEngine.bindCamera(this.scene.getCamera());
        this.shaderEngine.bindTextureUnitMapping();
        
        this.renderGeometry(this.scene.getGeometry());
        
        this.scene.clearGeometry();
        this.scene.clearSoundSources();
    }
    
    private void renderGeometry(TriGroupBuffer geometry)
    {
        for (int i = 0; i < geometry.getNumTriGroups(); i++)
        {
            TriGroup triGroup = geometry.getTriGroupAt(i);
            this.shaderEngine.bindMatrixModel(triGroup.getMatrixModel());
            triGroup.render();
        }
    }
    
    public void destroy()
    {
        this.scene = null;
        this.shaderEngine.destroy();
        this.glEngine.destroy();
    }
    
}
